package com.jerei.web.utils.spring;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jerei.utils.UtilsCommon;
import com.jerei.utils.UtilsDate;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.springframework.web.servlet.view.document.AbstractXlsxView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.Map;

/**
 * Created by sunfeihu on 2016/11/16.
 */
public class BaseExcelView extends AbstractXlsxView {


    @Override
    protected void buildExcelDocument(Map<String, Object> model, org.apache.poi.ss.usermodel.Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String data = UtilsCommon.getString(model.get("data"));
        String options = UtilsCommon.getString(model.get("options"));
        String fields = UtilsCommon.getString(model.get("fields"));
        JSONArray fieldsArr = null;
        if (null != fields && !"".equals(fields)) {
            fieldsArr = JSONArray.parseArray(fields);
        }
        JSONObject opt = new JSONObject();
        opt.put("fileName", UtilsDate.getToday("yyyyMMddHHmmss"));
        opt.put("sheetName", UtilsDate.getToday("yyyyMMddHHmmss"));
        if (null != options && !"".equals(options)) {
            JSONObject _opt = JSONObject.parseObject(options);
            for (String key : opt.keySet()) {
                opt.put(key, opt.get(key));
            }
            if (null != _opt && null != _opt.getJSONArray("fields")) {
                fieldsArr = _opt.getJSONArray("fields");
            }
        }
        if (null != data && !"".equals(data)) {
            JSONObject obj = JSONObject.parseObject(data);
            JSONArray rows = obj.getJSONArray("rows");
            JSONObject fieldObj = null;
            if (null != rows && rows.size() > 0) {
                JSONObject _obj = null;
                XSSFSheet sheet = (XSSFSheet) workbook.createSheet(opt.getString("sheetName"));
                sheet.setDefaultColumnWidth((short) 12);
                XSSFRow row = null;
                XSSFCell cell = null;
                XSSFCellStyle cellStyle = null;
                Font font = null;
                row = sheet.createRow(0);
                //先创建表头
                for (int j = 0; j < fieldsArr.size(); j++) {
                    fieldObj = fieldsArr.getJSONObject(j);
                    cell = row.createCell(j);
                    cell.setCellValue(fieldObj.getString("title"));
                    cellStyle = (XSSFCellStyle) workbook.createCellStyle();
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle.setFillBackgroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
                    cellStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
                    font = workbook.createFont();
                    font.setBold(true);
                    font.setFontName("微软雅黑");
                    font.setFontHeightInPoints((short) 12);
                    cellStyle.setFont(font);
                    cell.setCellStyle(cellStyle);
                    sheet.setColumnWidth(j, fieldObj.getInteger("boxWidth") * 50);
                    sheet.setVerticallyCenter(true);
                }
                font = workbook.createFont();
                font.setBold(false);
                font.setFontName("微软雅黑");
                font.setFontHeightInPoints((short) 10);
                for (int i = 0; i < rows.size(); i++) {
                    _obj = rows.getJSONObject(i);
                    row = sheet.createRow(i + 1);
                    for (int j = 0; j < fieldsArr.size(); j++) {
                        fieldObj = fieldsArr.getJSONObject(j);
                        cell = row.createCell(j);
                        cellStyle = (XSSFCellStyle) workbook.createCellStyle();
                        cellStyle.setFont(font);
                        if (fieldObj.getString("align").equals("left")) {
                            cellStyle.setAlignment(HorizontalAlignment.LEFT);
                        } else if (fieldObj.getString("align").equals("right")) {
                            cellStyle.setAlignment(HorizontalAlignment.RIGHT);
                        } else {
                            cellStyle.setAlignment(HorizontalAlignment.CENTER);
                        }
                        cell.setCellStyle(cellStyle);
                        cell.setCellValue(_obj.getString(fieldObj.getString("field")));
                    }
                }
                String filename = opt.getString("fileName") + ".xlsx";
                filename = this.encodeFilename(filename, request);
                response.setContentType("application/vnd.ms-excel");
                response.setHeader("Content-disposition", "attachment;filename=" + filename);
            }
        }
    }

    private String encodeFilename(String filename, HttpServletRequest request) {
        String agent = request.getHeader("USER-AGENT");
        try {
            if ((agent != null) && (-1 != agent.indexOf("MSIE"))) {
                String newFileName = URLEncoder.encode(filename, "UTF-8");
                newFileName = StringUtils.replace(newFileName, "+", "%20");
                if (newFileName.length() > 150) {
                    newFileName = new String(filename.getBytes("GB2312"), "ISO8859-1");
                    newFileName = StringUtils.replace(newFileName, " ", "%20");
                }
                return newFileName;
            }
            if ((agent != null) && (-1 != agent.indexOf("Mozilla")))
                return URLEncoder.encode(filename, "UTF-8");

            return filename;
        } catch (Exception ex) {
            return filename;
        }
    }
}
